#include <vector>
#include <map>
#include <algorithm>
using namespace std;

class Solution {
public:
    vector<vector<int>> threeSumTarget(vector<int>& num, long long target) {
        vector<vector<int>> res;
        sort(num.begin(), num.end());
        int n = num.size();

        for (int i = 0; i < n; i++) {
            if (i > 0 && num[i] == num[i - 1]) continue;

            long long newTarget = target - num[i];
            map<long long, int> mp;
            for (int j = i + 1; j < n; j++) {
                long long need = newTarget - num[j];
                if (mp.count(need)) {
                    vector<int> triplet = {num[i], (int)need, num[j]};
                    sort(triplet.begin(), triplet.end());
                    res.push_back(triplet);
                    while (j + 1 < n && num[j] == num[j + 1]) j++;
                }
                mp[num[j]] = j;
            }
        }

        sort(res.begin(), res.end());
        res.erase(unique(res.begin(), res.end()), res.end());
        return res;
    }

    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> res;
        sort(nums.begin(), nums.end());
        int n = nums.size();

        for (int i = 0; i < n; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            vector<int> cur(nums.begin() + i + 1, nums.end());
            vector<vector<int>> triples = threeSumTarget(cur, (long long)target - nums[i]);
            for (auto& t : triples) {
                t.push_back(nums[i]);
                sort(t.begin(), t.end());
                res.push_back(t);
            }
        }

        sort(res.begin(), res.end());
        res.erase(unique(res.begin(), res.end()), res.end());
        return res;
    }
};
